import os
import sys
from datetime import datetime

from dnscope.registry import call_hook
from dnscope import fs
from dnscope.decorator import after, before, testcase
from dnscope.core import TestSuit, TotalResult
from dnscope.exception import ServerStartError

version = '2.1.0'

__all__ = ['after','before','testcase','call_hook']

class Runner(object):
    '''Main dnscope's test runner

    Takes a base path as parameter, so that it can look for
    test scripts on there.
    '''

    def __init__(self, base_path, tests=None):

        if not os.path.isdir(base_path):
            sys.stderr.write("Dir %s not exist!\n" % base_path)
            raise SystemExit(1)

        os.environ['CASE_TOP'] = base_path
        self.loader = fs.TestLoader(base_path)

        # read input tests 
        self.tests = tests and self.__parse_tests_input(tests) or None

        # load output decorators
        from dnscope.plugins import colored_shell_output as output
        reload(output)
        self.output = output
        
    def __parse_tests_input(self, tests):
          
        if not tests:
            return 

        parse_result = {} 
        for single_test in tests.split(","):
            single_test = single_test.strip(" ")
            single_test = single_test.strip(".")
            if not single_test: continue

            if single_test.find(".", 0, len(single_test)) != -1:
                suit, test = single_test.split(".")

                if suit in parse_result.keys():
                       parse_result[suit].append(test)
                else:
                       parse_result[suit] = [test]

            else:
                parse_result[single_test] = '*' 
 
        return parse_result
				 
 
    def run(self):

        started_at = datetime.now()
        
        # load test scripts
	self.loader.load_test_scripts()

	allsuits = self.loader.get_testsuits() 
	if not allsuits:
	    # no suits found
            print "No testsuits in TEST_REGISTRY"
	    return

	# call_hook(before all)
	call_hook('before', 'all')

        failed = False
        results = []

        try:
	    if not self.tests:
		for eachsuit in allsuits:
		    testsuit = TestSuit(eachsuit)
                    results.append(testsuit.run())
	    else:
		for suit in self.tests.keys():
		    tests_to_run = self.tests[suit]
                    if suit == '*':
                        for eachsuit in allsuits:
                            testsuit = TestSuit(eachsuit)
                            results.append(testsuit.run(tests_to_run))
                        
                        continue
                    
		    testsuit = TestSuit(suit)
		    if tests_to_run == '*' or tests_to_run == ['*']:
		        results.append(testsuit.run())
                    else:
			results.append(testsuit.run(tests_to_run))

        finally:
            total = TotalResult(results)
            call_hook('after', 'all', total)

            fineshed_at = datetime.now()
            time_took = fineshed_at - started_at

            hours = time_took.seconds / 60 / 60
            minutes = time_took.seconds / 60
            seconds = time_took.seconds 
            if hours:
                print "(finished within %d hours)" % hours
            elif minutes:
                print "(finished within %d minutes)" % minutes
            elif seconds:
                print "(finished within %d seconds)" % seconds

            
        return total


if __name__ == '__main__':

    base_path = 'cases'
   
    # normal cases
    print "****dnscope"
    runner = Runner(base_path)
    print runner.tests
    runner.run()

    print "****dnscope -t query"
    runner = Runner(base_path,'query')
    print runner.tests
    runner.run()

    print "****dnscope -t query,axfr"
    runner = Runner(base_path,'query,axfr')
    print runner.tests
    runner.run()

    print "****dnscope -t query.qtype"
    runner = Runner(base_path,'query.qtype')
    print runner.tests
    runner.run()

    print "****dnscope -t query.dnssec, axfr.c09"
    runner = Runner(base_path,'query.dnssec,axfr.c09')
    print runner.tests
    runner.run()

    print "****dnscope -t query, axfr.c09"
    runner = Runner(base_path,'query, axfr.c09')
    print runner.tests
    runner.run()

    print "****dnscope -t axfr,query"
    runner = Runner(base_path,'axfr,query')
    print runner.tests
    runner.run()

    print "****dnscope -t query.*"
    runner = Runner(base_path,'query.*')
    print runner.tests
    runner.run()

    print "****dnscope -t *.dnssec"
    runner = Runner(base_path,'*.dnssec')
    print runner.tests
    runner.run()

    # abnormal cases
    print "****dnscope -t .dnssec"
    runner = Runner(base_path,'.dnssec')
    print runner.tests
    runner.run()

    print "****dnscope -t query."
    runner = Runner(base_path,'query.')
    print runner.tests
    runner.run()

    print "****dnscope -t nxsuit.qtype"
    runner = Runner(base_path,'nxsuit.qtype')
    print runner.tests
    runner.run()

    print "****dnscope -t query.nxtest"
    runner = Runner(base_path,'query.nxtest')
    print runner.tests
    runner.run()
